package com.guosen.zebra.framework.starter.http.log.filter;

import com.guosen.zebra.framework.starter.http.log.properties.HttpLogProperties;
import com.guosen.zebra.framework.starter.http.log.utils.HttpLogHelper;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static com.guosen.zebra.framework.starter.http.log.constants.HttpLogConstant.*;

/**
 * http请求记录过滤器
 */
public class InterfaceLogFilter extends OncePerRequestFilter {

    private final HttpLogProperties httpLogProperties;

    public InterfaceLogFilter(HttpLogProperties httpLogProperties) {
        this.httpLogProperties = httpLogProperties;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        ContentCachingRequestWrapper wrappedRequest = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper wrappedResponse = new ContentCachingResponseWrapper(response);
        request.setAttribute(ZEBRA_HTTP_LOG_START_TIME, System.currentTimeMillis());

        filterChain.doFilter(wrappedRequest, wrappedResponse);

        request.setAttribute(ZEBRA_HTTP_LOG_END_TIME, System.currentTimeMillis());
        logBizReqIfEnabled(wrappedRequest);
        logAccIfEnabled(wrappedRequest, wrappedResponse);
        logBizRspIfEnabled(wrappedRequest, wrappedResponse);
        wrappedResponse.copyBodyToResponse();  // IMPORTANT: copy content of response back into original response
    }

    private void logBizReqIfEnabled(ContentCachingRequestWrapper req) {
        boolean reqEnabled = httpLogProperties.getBiz().isReqEnabled();
        if (reqEnabled)
            HttpLogHelper.logBizRequest(req);
    }

    private void logAccIfEnabled(ContentCachingRequestWrapper req, ContentCachingResponseWrapper rsp) {
        boolean enabled = httpLogProperties.getAcc().isEnabled();
        if (enabled)
            HttpLogHelper.logAcc(req, rsp);
    }

    private void logBizRspIfEnabled(ContentCachingRequestWrapper req, ContentCachingResponseWrapper rsp) {
        boolean rspEnabled = httpLogProperties.getBiz().isRspEnabled();
        if (rspEnabled)
            HttpLogHelper.logBizResponse(req, rsp);
    }
}
